if(structs==nil)then
    structs = {};
end
require("drw");


local function writeValue(d,struct,k,v)
    assert(struct[k]);
    local s = struct[k];
    if(isinteger(s))then return; end;     --  type(1size) == integer
    local bpos = s.bpos;
    local bsiz = s.bsiz;
    bpos = bpos>>3;
    bsiz = bsiz>>3;
    --print(bpos,bsiz,v);
    --integer_type
    if(s.type=="pointer_type")then
        v = dint(v);
    end
    return dw(d,bpos,bsiz,v);
end

local function readValue(d,struct,k)
    assert(struct[k]);
    local s = struct[k];
    local bpos = s.bpos;
    local bsiz = s.bsiz;
    bpos = bpos>>3;
    bsiz = bsiz>>3;
    if(s.type=="record_type")then
        local ptr = dpointer(d,bpos);
        return toType(ptr,s.tname);
    elseif(s.type=="pointer_type")then
        local ptr = dpointer(dr(d,bpos,bsiz));
        return toType(ptr,s.tname);
    end
    --print(bpos,bsiz);
    return dr(d,bpos,bsiz);
end


function toType(a,typ)
    a = touserdata(a);
    local struct;
    --print(typ,structs[typ]);
    if(isstring(typ))then
        struct = structs[typ];
    else
        struct = typ;
    end
    local metatable = {
        __index = function(d,k)
            if(isinteger(k))then
                local ptr = dpointer(d,k*struct["1size"]);
                return toType(ptr,struct);
            end
            return readValue(d,struct,k);
        end,
        __newindex = function(d,k,v)
            writeValue(d,struct,k,v);
        end,
        __gc = function(a)
            local gc = getmetatable(a).__xgc;
            if(gc)then
                return gc(a);
            end
        end
    };
    udsetmetatable(a,metatable);
    return a;
end

function point4table(point,t,typ)
    local struct = structs[typ];
    for k,v in pairs(struct) do
        writeValue(point,struct,k,v);
    end
    return point;
end

function getTypeSize(typ)
    local struct = structs[typ];
    local siz = struct["1size"];
    if((siz&7)==0) then return siz >>3; end;
    siz = siz + (8-(siz&7));
    return siz >> 3;
end

function D(obj,typ)
    return toType(obj,typ);
end

function cast(obj,typ)
    return toType(obj,typ);
end

function set__gc(a,f)
    getmetatable(a).__xgc = f;
end

T = cast

--test
function SDL_Rect()
    return SDL_calloc(4*4,1),"SDL_Rect";
end

